#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
//struct student
//{
//	int order;
//	char name[20];
//};
//struct node
//{
//	struct student data;
//	struct node* next;
//};
//struct linkqueue
//{
//	struct node* front;
//	struct node* rear;
//};
//struct linkqueue* queueInit()
//{
//	struct linkqueue* p = (struct linkqueue*)malloc(sizeof(struct linkqueue));
//	if (p == NULL)
//	{
//		printf("malloc fail");
//		return NULL;
//	}
//	p->front = p->rear = NULL;
//	return p;
//}
//bool is_empty(struct linkqueue* p)
//{
//	if (p->front == NULL && p->rear == NULL)
//		return true;
//	else
//		return false;
//}
//bool enqueue(struct linkqueue* p, int o, char* n)
//{
//	struct node* newnode = (struct node*)malloc(sizeof(struct node));
//	if (newnode == NULL)
//	{
//		printf("malloc fail");
//		return false;
//	}
//	newnode->data.order = o;
//	strcpy(newnode->data.name, n);
//	newnode->next = NULL;
//	if (is_empty(p))
//	{
//		p->front = p->rear = newnode;
//	}
//	else
//	{
//		p->rear->next = newnode;
//		p->rear = newnode;
//	}
//	return true;
//}
//bool out_queue(struct linkqueue* p, struct student* val)
//{
//	if (is_empty(p))
//		return false;
//	*val = p->front->data;
//	struct node* tmp = p->front->next;
//	free(p->front);
//	p->front = tmp;
//	if (p->front == NULL)
//		p->rear = p->front;
//	return true;
//}
//void show(struct linkqueue* p)
//{
//	if (is_empty(p))
//		return;
//	struct node* tmp = p->front;
//	while (tmp != p->rear)
//	{
//		printf("num:%d\t name:%s", tmp->data.order, tmp->data.name);
//		tmp = tmp->next;
//	}
//	printf("num:%d\tname:%s\n", p->rear->data.order, p->rear->data.name);
//}
//void destory(struct linkqueue* p)
//{
//	if (is_empty(p))
//		return;
//	struct node* tmp = p->front;
//	while (tmp != p->rear)
//	{
//		free(tmp);
//		tmp = tmp->next;
//	}
//	free(p->rear);
//	p->front = p->rear = NULL;
//}
//int main()
//{
//	int order = 0;
//	struct student c;
//	char name[50] = { 0 };
//	int num = 0;
//	struct linkqueue* pq = queueInit();
//	while(1)
//	{
//		printf("1. 2. 3.4.");
//		scanf("%d", &num);
//		switch (num)
//		{
//		case 1:
//			scanf("%s", name);
//			enqueue(pq, ++order, name);
//			break;
//		case 2:
//			out_queue(pq, &c);
//			printf("num:%d \tname%s", c.order, c.name);
//			break;
//		case 3:
//			show(pq);
//			break;
//		case 4:
//			destory(pq);
//			break;
//		}
//	}
//	return 0;
//}
typedef struct dancer
{
	char sex;
	char name[30];
}dan;

typedef struct loop_queue
{
	dan* d;
	int f;
	int r;
}lop;
#define SIZE 10
lop* queueInit()
{
	lop* p = (lop*)malloc(sizeof(lop));
	if (p == NULL)
	{
		printf("malloc fail");
		return NULL;
	}
	p->d = (dan*)malloc(sizeof(dan) * SIZE);
	if (p->d == NULL)
	{
		free(p);
		return NULL;
	}
	p->f = p->r = 0;
	return p;
}
bool is_empty(lop* p)
{
	if (p->f == p->r)
		return true;
	else
		return false;
}
bool is_full(lop* p)
{
	if (p->f == (p->r + 1) % SIZE)
		return true;
	else
		return false;
}
bool en_queue(lop* p, dan d)
{
	if (is_full(p))
		return false;
	p->d[p->r] = d;
	p->r = (p->r + 1) % SIZE;
	return true;
}
bool out_queue(lop* p, dan* val)
{
	if (is_empty(p))
		return false;
	*val = p->d[p->f];
	p->f = (p->f + 1) % SIZE;
	return true;
}
bool get_head(lop* p, dan* val)
{
	if (is_empty(p))
		return false;
	*val = p->d[p->f];
	return true;
}
void match(dan* dancer, int num)
{
	lop* fq = queueInit();
	lop* mq = queueInit();
	dan d;
	int i = 0;
	for (i = 0; i < num; i++)
	{
		d = dancer[i];
		if (d.sex == 'f')
		{
			en_queue(fq, d);
		}
		else
		{
			en_queue(mq, d);
		}
	}
	while (!is_empty(fq) && !is_empty(mq))
	{
		out_queue(fq, &d);
		printf("%s", d.name);
		out_queue(mq, &d);
		printf("%s\n", d.name);
	}
	if (!is_empty(fq))
	{
		get_head(fq, &d);
		printf("%s\n", d.name);
	}
	if (!is_empty(mq))
	{
		get_head(mq, &d);
		printf("%s\n", d.name);
	}
}
int main()
{
	dan dancer[5];
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		scanf("%s %c", &dancer[i].name, &(dancer[i].sex));
		getchar();
	}
	match(dancer, 5);
	return 0;
}